package com.itkjb.leisurely.resource.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itkjb.leisurely.core.base.service.impl.BaseServiceImpl;
import com.itkjb.leisurely.core.exception.LeisurelyException;
import com.itkjb.leisurely.core.model.SearchModel;
import com.itkjb.leisurely.resource.sys.mapper.SysDictMapper;
import com.itkjb.leisurely.resource.sys.model.SysDictModel;
import com.itkjb.leisurely.resource.sys.model.vo.SysDictVO;
import com.itkjb.leisurely.resource.sys.service.ISysDictGroupService;
import com.itkjb.leisurely.resource.sys.service.ISysDictService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 系统字典表 服务实现类
 * </p>
 *
 * @author leisure_gen
 * @since leisure_gen
 */
@Service
public class SysDictServiceImpl extends BaseServiceImpl<SysDictMapper, SysDictModel> implements ISysDictService {

    @Autowired
    private ISysDictGroupService sysDictGroupService;
    /**
     * wrapper 组装器，构造条件查询
     * @author leisure_gen
     * @date  leisure_gen
     * @param wrapper
     * @param model 条件
     **/
    @Override
    protected void assembleWrapper(QueryWrapper<SysDictModel> wrapper, SysDictModel model) {
        // 字典类型
        wrapper.lambda().eq(model.getDictType()!=null ,SysDictModel::getDictType,model.getDictType());
        // 字典分组
        if(StringUtils.isNotBlank(model.getDictGroupId())){
            Set<String> subIds = this.sysDictGroupService.getSubIds(model.getDictGroupId());
            if(subIds == null){
                subIds = new HashSet<>();
            }
            subIds.add( model.getDictGroupId());
            wrapper.lambda().in(SysDictModel::getDictGroupId,subIds);
        }

        // 字典标签
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getDictLabel()), SysDictModel::getDictLabel,model.getDictLabel());
        // 字典父级id
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getParentId()), SysDictModel::getParentId, model.getParentId());
        // 字典 key
        wrapper.lambda().eq(StringUtils.isNotBlank(model.getKey()), SysDictModel::getKey, model.getKey());
        // 字典值（模糊查询）
        wrapper.lambda().like(StringUtils.isNotBlank(model.getValue()), SysDictModel::getValue, model.getValue());
        // 字典状态
        wrapper.lambda().eq(model.getStatus() != null, SysDictModel::getStatus  ,model.getStatus());
    }

    /**
     * 校验保存或更新时字典的label 标签是否已存在
     * @param label
     * @param id
     * @return
     */
    @Override
    public boolean labelIsExist(String label, String id){
        if(StringUtils.isBlank(label)){
            throw new LeisurelyException("检查的字典标识不能为空");
        }
        return labelOrKeyIsExit(label, null, id,true);
    }
    /**
     * 校验保存或更新时字典详情的key 索引是否已存在
     * @param label
     * @param id
     * @return
     */
    @Override
    public boolean keyIsExist(String label, String key, String id){
        if(StringUtils.isBlank(key)){
            throw new LeisurelyException("检查的字典索引不能为空");
        }
        return labelOrKeyIsExit(label, key, id,false);
    }


    /**
     * 查询字典或字典详情是否已存在，key为空时，查询的是字典 label
     * @param label
     * @param key 可以为空
     * @param id 更新时传入，新增时传入null，主要为了在更新时排除自身数据
     * @param isLabel 是否是字典标识 label  ，trye label， false ：key
     * @return
     */
    private boolean labelOrKeyIsExit(String label, String key,String id ,boolean  isLabel){
        QueryWrapper<SysDictModel> wrapper =new QueryWrapper<>();
        if(isLabel){
            // key 为空，查询的是字典数据 label
            wrapper.lambda().eq(SysDictModel::getDictType,0);
        }else{
            // key 不为空，查询的是字典详情，字典索引数据
            wrapper.lambda().eq(SysDictModel::getDictType,1);
            wrapper.lambda().eq(SysDictModel::getKey, key);
        }
        // 查询的标签
        wrapper.lambda().eq(SysDictModel::getDictLabel,label);
        // 查询未删除的
        wrapper.lambda().eq(SysDictModel::getIsDel, 0);
        // id 不为空时，排除自身数据
        wrapper.lambda().ne(StringUtils.isNotBlank(id),SysDictModel::getId,id);
        List<SysDictModel> sysDictModels = this.baseMapper.selectList(wrapper);
        if(sysDictModels !=null && sysDictModels.size()>0){
            // 已存在
            return true;
        }
        return false;
    }
    @Override
    public boolean save(SysDictModel entity) {
        if(this.labelOrKeyIsExit(entity.getDictLabel(),entity.getKey(),null,entity.getDictType() ==0)){
            throw new LeisurelyException("该字典标识或者索引已存在！");
        }
        return super.save(entity);
    }

    @Override
    public boolean updateById(SysDictModel entity) {
        if(this.labelOrKeyIsExit(entity.getDictLabel(),entity.getKey(),entity.getId(),entity.getDictType() ==0)){
            throw new LeisurelyException("该字典标识或者索引已存在！");
        }
        return super.updateById(entity);
    }

    /**
     * 根据新的label 更新字典详情中的label
     * @param oldDictLabel 原始的label
     * @param newDictLabel 新的label
     * @return
     */
    @Override
    public int updateByLabel(String oldDictLabel, String newDictLabel){
        boolean b = this.labelIsExist(newDictLabel, null);
        if(b){
            throw new LeisurelyException("该字典标识已存在！请更换字典标识！");
        }
        SysDictModel model = new SysDictModel();
        model.setDictLabel(newDictLabel);
        QueryWrapper<SysDictModel> wrapper =new QueryWrapper<>();
        wrapper.lambda().eq(SysDictModel::getDictLabel,oldDictLabel).eq(SysDictModel::getDictType, 1);
        return this.baseMapper.update(model,wrapper);
    }

    /**
     * 根据传入的dictLabel 查找相应的字典详情
     * @param searchModel
     * @return
     */
    @Override
    public List<SysDictVO> getDictDetail(SearchModel<SysDictModel> searchModel){
        QueryWrapper<SysDictModel> wrapper  = new QueryWrapper<>();
        // 设置查询返回的字段
        wrapper.lambda().select(SysDictModel::getId,SysDictModel::getDictLabel,SysDictModel::getKey,SysDictModel::getValue);
        assembleWrapper(wrapper, searchModel.getModel());
        List<SysDictModel> list = list(wrapper);
        List<SysDictVO> res = new ArrayList<>(list.size());
        list.forEach(model ->{
            SysDictVO vo = new SysDictVO();
            BeanUtils.copyProperties(model, vo);
            res.add(vo);
        });
        return res;
    }

    @Override
    protected void buildListSelectColumns(QueryWrapper<SysDictModel> wrapper, SysDictModel model) {

    }
}
